﻿using System;
using System.IO;

namespace Borg.Framework
{
    public class ScriptReader
    {
        private readonly IScriptExecutor _executor;
        private readonly ExtensionInfo _ext;

        public ScriptReader(IScriptExecutor executor, ExtensionInfo ext)
        {
            _executor = executor;
            _ext = ext;
        }

        public void ExecuteScript(string script)
        {
            using (var getter = new ResourceStreamGetter(
                _ext.ExtensionTypeInfo.PluginInfo, script, false))
            {
                string str;

                using (var reader = new StreamReader(getter.Stream))
                    str = reader.ReadToEnd();

                _executor.ExecuteAsync(str, ScriptCompleted);
            }
        }

        public static void ExecuteScript(string scriptPath, ExtensionInfo ext)
        {
            if (string.IsNullOrEmpty(scriptPath))
                ext.LogEvent(
                    new LogEventArgs(
                        MessageType.Error,
                        VerbosityLevel.Minimal,
                        "script path is empty."));

            else if (!File.Exists(scriptPath))
                ext.LogEvent(
                    new LogEventArgs(
                        MessageType.Error,
                        VerbosityLevel.Minimal,
                        "script file not found: \"{0}\"",
                        new object[] {scriptPath}));
            else
            {
                try
                {
                    using (var reader = new StreamReader(scriptPath))
                    {
                        string str;

                        var interpreter = new CommandInterpreter();
                        var commands = new RuntimeCommands();

                        foreach (var command in commands.Commands)
                            interpreter.commands.Add(command.Name, command);

                        ext.LogEvent(
                            new LogEventArgs(
                                MessageType.Info,
                                VerbosityLevel.Normal,
                                "script \"{0}\" started",
                                new object[] {scriptPath}));

                        while ((str = reader.ReadLine()) != null)
                        {
                            var str2 = interpreter.Execute(str);
                            var str3 = string.Format("command: \"{0}\"", str);

                            if (!string.IsNullOrEmpty(str2))
                                str3 = string.Format("{0}{1}  {2}", str3, Environment.NewLine, str2);

                            ext.LogEvent(
                                new LogEventArgs(
                                    MessageType.Info,
                                    VerbosityLevel.Diagnostic,
                                    str3));
                        }

                        ext.LogEvent(
                            new LogEventArgs(
                                MessageType.Info,
                                VerbosityLevel.Normal,
                                "script \"{0}\" finished",
                                new object[] {scriptPath}));
                    }
                }
                catch (Exception exception)
                {
                    ext.LogEvent(
                        new LogEventArgs(
                            MessageType.Error,
                            VerbosityLevel.Minimal,
                            "error on reading script file: \"{0}\"",
                            new object[] {scriptPath}));

                    ext.LogEvent(
                        new LogEventArgs(
                            MessageType.Error,
                            VerbosityLevel.Minimal,
                            exception.ToString()));
                }
            }
        }

        private void ScriptCompleted(object s, ScriptCompletedEventArgs args)
        {
            _ext.LogEvent(args.Result.StateMessage);
        }
    }
}

